package com.example.crondemo.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.crondemo.exception.TaskException;
import com.example.crondemo.model.Stock;
import com.example.crondemo.mapper.StockMapper;
import com.example.crondemo.model.vo.StockQueryVo;
import com.example.crondemo.result.ResultCodeEnum;
import com.example.crondemo.service.StockService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.crondemo.utils.CommonConfig;
import org.apache.ibatis.session.SqlSessionException;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yanbl
 * @since 2021-06-30
 */
@Service
public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements StockService {

    @Autowired
    private CommonConfig commonConfig;

    @Autowired
    private StockMapper stockMapper;

    /**
     * 分页查询数据库
     *
     * @param page
     * @param limit
     * @param stockQueryVo
     * @return
     */
    @Override
    public Page<Stock> findByCondition(Integer page, Integer limit, StockQueryVo stockQueryVo) throws TaskException {
        // 创建page对象，传递参数，每页记录数量
        Page<Stock> currentPage = new Page<>(page, limit);
        // 构建查询对象
        QueryWrapper<Stock> stockQueryWrapper = new QueryWrapper<>();

        // 判断查询对象是否为空
        if (ObjectUtils.isNotEmpty(stockQueryVo)) {

            // 开始时间和结束时间是否为空
            if (ObjectUtils.isNotEmpty(stockQueryVo.getStartTime()) && ObjectUtils.isNotEmpty(stockQueryVo.getEndTime())) {

                // 判断时间是否查过30天 超过抛出异常
                if (this.isThanOneMouth(stockQueryVo.getStartTime(), stockQueryVo.getEndTime())) {
                    throw new TaskException(ResultCodeEnum.THANONEMOUTH);
                }
                // 查询
                stockQueryWrapper.between("created", stockQueryVo.getStartTime(), stockQueryVo.getEndTime());
            }
            // 如果条形码不为空
            if (StringUtils.isNotBlank(stockQueryVo.getBarCode())) {
                stockQueryWrapper.like("barcode", stockQueryVo.getBarCode());
            }

            // 仓库编号不为空
            if (StringUtils.isNotBlank(stockQueryVo.getWarehouseNo())) {
                stockQueryWrapper.eq("warehouse_no", stockQueryVo.getWarehouseNo());
            }
        }

        try {
            // 获取查询结果
            currentPage = stockMapper.selectPage(currentPage, stockQueryWrapper);
        } catch (SqlSessionException e) {
            e.printStackTrace();
        }

        return currentPage;
    }

    /**
     * 插入数据库
     *
     * @param stocks
     * @return
     */
    public void addStocks(List<Stock> stocks) {
        // 默认为false
        boolean b = false;
        // 如果不为空则添加数据库
        if (ObjectUtils.isNotEmpty(stocks)) {
            stocks.forEach(stock -> {
                // 查询条件 判断数据库是否有此数据
                QueryWrapper<Stock> rec_id = new QueryWrapper<>();
                rec_id.eq("rec_id", stock.getRecId());
                Stock selectOne = baseMapper.selectOne(rec_id);
                // 数据库 不为空则修改
                if (ObjectUtils.isNotEmpty(selectOne)) {
                    baseMapper.update(stock, rec_id);
                } else {
                    // rec_id 数据库为空则添加
                    baseMapper.insert(stock);
                }
            });
        }
    }

    /**
     * 根据开始和结束时间来查询接口中库存数量
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public List<Stock> findStockInvoke(String startTime, String endTime) throws TaskException {

        // TODO Auto-generated method stub
        // 开始和结束时间
        Map<String, String> params = new HashMap<String, String>();
        params.put("start_time", startTime);
        params.put("end_time", endTime);
        List<Stock> stockList = new ArrayList<>();

        try {
            // 响应结果
            String response = commonConfig.getResponse(params);

            // 解析响应结果
            JSONObject result = JSONObject.parseObject(response);
            JSONArray stocks = result.getJSONArray("stocks");

            if (ObjectUtils.isNotEmpty(stocks)) {
                // 把json转换为model
                for (int i = 0; i < stocks.size(); i++) {
                    String jsonString = stocks.getJSONObject(i).toJSONString();
                    Stock stock = JSONObject.parseObject(jsonString, Stock.class);
                    // 添加到数组中
                    stockList.add(stock);
                }
            }
            // 返回结果
            return stockList;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            // 异常则返回空
            return null;
        }
    }

    // 判断时间是否超过30天
    public boolean isThanOneMouth(String startTime, String endTime) {
        boolean flag = false; // false为没超过

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date startDateTime = sdf.parse(startTime);
            // 获取30天后的时间
            DateTime afterDay = new DateTime(startDateTime).plusDays(30);
            // 结束时间
            DateTime endDateTime = new DateTime(sdf.parse(endTime));
            // 如果30天后的时间小于结束时间 抛出异常
            if (afterDay.isBefore(endDateTime)) {
                // start_time与end_time时间跨度不能超过最大范围 30天
                flag = true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return flag;
    }
}
